import 'dart:math';

import 'package:flutter/material.dart';
import 'package:bruno/bruno.dart';

import 'onenet.dart';

Widget brokenLine(context, List<DBDataNodeModel>? brokenData, ScrollController controller) {
  if (brokenData == null) return Container();
  return Column(
    children: <Widget>[
      BrnCommonCardTitle(
        title: '数据模板',
        accessoryText: dev.dsid,
      ),
      BrnBrokenLine(
        showPointDashLine: true,
        yHintLineOffset: 25,
        isTipWindowAutoDismiss: false,
        lines: [
          BrnPointsLine(
            isShowPointText: true,
            isShowXDial: true,
            lineWidth: 3,
            pointRadius: 4,
            isShowPoint: true,
            isCurve: true,
            points: _linePoints(brokenData),
            shaderColors: [Colors.green.withOpacity(0.3), Colors.green.withOpacity(0.01)],
            lineColor: Colors.green,
          )
        ],
        size: Size(brokenData.length * 40, MediaQuery.of(context).size.height / 5 * 1.6),
        isShowXHintLine: true,
        xDialValues: _getXDialValues(brokenData),
        xDialMin: -1,
        xDialMax: _getXDialValues(brokenData).length.toDouble(),
        yDialValues: _getYDialValues(brokenData),
        yDialMin: _getMinValue(brokenData),
        yDialMax: _getMaxValue(brokenData) + 1,
        isHintLineSolid: false,
        isShowYDialText: true,
        scrollController: controller,
      ),
    ],
    crossAxisAlignment: CrossAxisAlignment.start,
  );
}

List<BrnPointData> _linePoints(List<DBDataNodeModel> brokenData) {
  return brokenData
      .map((_) => BrnPointData(
          pointText: _.value.toStringAsFixed(3).toString(),
          x: brokenData.indexOf(_).toDouble(),
          y: _.value,
          lineTouchData: BrnLineTouchData(
              tipWindowSize: const Size(60, 40),
              onTouch: () {
                return _.value;
              })))
      .toList();
}

List<BrnDialItem> _getYDialValues(List<DBDataNodeModel> brokenData) {
  double min = _getMinValue(brokenData);
  double max = _getMaxValue(brokenData);
  int step = 12;
  double dValue = (max - min) / step;
  List<BrnDialItem> _yDialValue = [];
  for (int index = 0; index <= step; index++) {
    _yDialValue.add(BrnDialItem(
      dialText: '${(min + index * dValue).ceil()}',
      dialTextStyle: const TextStyle(fontSize: 12.0, color: Color(0xFF999999)),
      value: (min + index * dValue).ceilToDouble(),
    ));
  }

  return _yDialValue;
}

double _getMinValue(List<DBDataNodeModel> brokenData) {
  double minValue = brokenData[0].value;
  for (DBDataNodeModel point in brokenData) {
    minValue = min(point.value, minValue);
  }
  return minValue;
}

double _getMaxValue(List<DBDataNodeModel> brokenData) {
  double maxValue = brokenData[0].value;
  for (DBDataNodeModel point in brokenData) {
    maxValue = max(point.value, maxValue);
  }
  return maxValue;
}

List<BrnDialItem> _getXDialValues(List<DBDataNodeModel> brokenData) {
  List<BrnDialItem> _xDialValue = [];
  for (int index = 0; index < brokenData.length; index++) {
    _xDialValue.add(BrnDialItem(
      dialText: index % 2 == 0 ? brokenData[index].name : '',
      dialTextStyle: const TextStyle(fontSize: 12.0, color: Color(0xFF999999)),
      value: index.toDouble(),
    ));
  }
  return _xDialValue;
}
